//
//  SGBaseModel.m
//  SGShow
//
//  Created by fanshijian on 15/10/13.
//  Copyright (c) 2015年 fanshijian. All rights reserved.
//

#import "SGBaseModel.h"
#import <objc/runtime.h>
#import "RMMapper.h"

@implementation SGBaseModel

+ (SGBaseModel *)shareInstance {
    static SGBaseModel *baseModel;
    if (!baseModel) {
        @synchronized(self) {
            if (!baseModel) {
                baseModel = [[SGBaseModel alloc] init];
            }
        }
    }
    return baseModel;
}



+ (instancetype)instanWithKeyValues:(NSDictionary *)dic{
    return [RMMapper objectWithClass:[self class] fromDictionary:dic];
}

- (NSMutableDictionary *)keyValues{
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    Class class = self.class;
    do {
        unsigned int propsCount;
        objc_property_t *props = class_copyPropertyList(class, &propsCount);
        for(int i = 0;i < propsCount; i++)
        {
            objc_property_t prop = props[i];
            
            NSString *propName = [NSString stringWithUTF8String:property_getName(prop)];
            id value = [self valueForKey:propName];
            if(value == nil)
            {
                value = [NSNull null];
            }
            else
            {
                value = [self getObjectInternal:value];
            }
            [dic setObject:value forKey:propName];
        }
        class = [class superclass];
    } while (class != [NSObject class]);
    
    return dic;
}

- (NSMutableDictionary *)keyValuesWithKeyPathMapper:(NSArray *)keyPaths{
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    unsigned int propsCount;
    objc_property_t *props = class_copyPropertyList(self.class, &propsCount);
    for(int i = 0;i < propsCount; i++)
    {
        objc_property_t prop = props[i];
        
        NSString *propName = [NSString stringWithUTF8String:property_getName(prop)];
        
        if ( !keyPaths || ![keyPaths containsObject:propName] ) {
            continue;
        }
        
        id value = [self valueForKey:propName];
        if(value == nil)
        {
            value = [NSNull null];
        }
        else
        {
            value = [self getObjectInternal:value];
        }
        [dic setObject:value forKey:propName];
    }
    return dic;
}

- (NSMutableDictionary *)keyValuesWithIgnoreKeyPathMapper:(NSArray *)keyPaths{
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    unsigned int propsCount;
    objc_property_t *props = class_copyPropertyList(self.class, &propsCount);
    for(int i = 0;i < propsCount; i++)
    {
        objc_property_t prop = props[i];
        
        NSString *propName = [NSString stringWithUTF8String:property_getName(prop)];
        
        if ( keyPaths && [keyPaths containsObject:propName] ) {
            continue;
        }
        
        id value = [self valueForKey:propName];
        if(value == nil)
        {
            value = [NSNull null];
        }
        else
        {
            value = [self getObjectInternal:value];
        }
        [dic setObject:value forKey:propName];
    }
    return dic;
}

- (id)getObjectInternal:(id)obj
{
    if([obj isKindOfClass:[NSString class]]
       || [obj isKindOfClass:[NSNumber class]]
       || [obj isKindOfClass:[NSNull class]])
    {
        return obj;
    }
    
    if([obj isKindOfClass:[NSArray class]])
    {
        NSArray *objarr = obj;
        NSMutableArray *arr = [NSMutableArray arrayWithCapacity:objarr.count];
        for(int i = 0;i < objarr.count; i++)
        {
            [arr setObject:[self getObjectInternal:[objarr objectAtIndex:i]] atIndexedSubscript:i];
        }
        return arr;
    }
    
    if([obj isKindOfClass:[NSDictionary class]])
    {
        NSDictionary *objdic = obj;
        NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:[objdic count]];
        for(NSString *key in objdic.allKeys)
        {
            [dic setObject:[self getObjectInternal:[objdic objectForKey:key]] forKey:key];
        }
        return dic;
    }
    return [obj keyValues];
}


- (BOOL)checkIsSelfInArray:(NSArray *)array {
    for (id data in array) {
        if ([[data class] isSubclassOfClass:[NSDictionary class]]) {
            return NO;
        }
    }
    return YES;
}

@end
